{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to configure multiple streaming modes at the same time\n",
    "\n",
    "This guide covers how to configure multiple streaming modes at the same time.\n",
    "\n",
    "## Setup\n",
    "\n",
    "First we need to install the packages required\n",
    "\n",
    "```bash\n",
    "npm install @langchain/langgraph @langchain/openai @langchain/core\n",
    "```\n",
    "\n",
    "Next, we need to set API keys for OpenAI (the LLM we will use)\n",
    "\n",
    "```bash\n",
    "export OPENAI_API_KEY=your-api-key\n",
    "```\n",
    "\n",
    "Optionally, we can set API key for [LangSmith tracing](https://smith.langchain.com/), which will give us best-in-class observability.\n",
    "\n",
    "```bash\n",
    "export LANGCHAIN_TRACING_V2=\"true\"\n",
    "export LANGCHAIN_CALLBACKS_BACKGROUND=\"true\"\n",
    "export LANGCHAIN_API_KEY=your-api-key\n",
    "```\n",
    "\n",
    "## Define the graph\n",
    "\n",
    "We'll be using a prebuilt ReAct agent for this guide."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { ChatOpenAI } from \"@langchain/openai\";\n",
    "import { tool } from '@langchain/core/tools';\n",
    "import { z } from 'zod';\n",
    "import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n",
    "\n",
    "const model = new ChatOpenAI({\n",
    "    model: \"gpt-4o\",\n",
    "  });\n",
    "\n",
    "const getWeather = tool((input) => {\n",
    "  if ([\"sf\", \"san francisco\", \"san francisco, ca\"].includes(input.location.toLowerCase())) {\n",
    "    return \"It's 60 degrees and foggy.\";\n",
    "  } else {\n",
    "    return \"It's 90 degrees and sunny.\";\n",
    "  }\n",
    "}, {\n",
    "  name: \"get_weather\",\n",
    "  description: \"Call to get the current weather.\",\n",
    "  schema: z.object({\n",
    "    location: z.string().describe(\"Location to get the weather for.\"),\n",
    "  })\n",
    "})\n",
    "\n",
    "const graph = createReactAgent({ llm: model, tools: [getWeather] });"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stream Multiple\n",
    "\n",
    "To get multiple types of streamed chunks, pass an array of values under the `streamMode` key in the second argument to `.stream()`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task',\n",
      "  timestamp: '2024-08-30T20:58:58.404Z',\n",
      "  step: 1,\n",
      "  payload: {\n",
      "    id: '768110dd-6004-59f3-8671-6ca699cccd71',\n",
      "    name: 'agent',\n",
      "    input: { messages: [Array] },\n",
      "    triggers: [ 'start:agent' ],\n",
      "    interrupts: []\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: updates\n",
      "{\n",
      "  agent: {\n",
      "    messages: [\n",
      "      AIMessage {\n",
      "        \"id\": \"chatcmpl-A22zqTwumhtW8TMjQ1FxlzCEMBk0R\",\n",
      "        \"content\": \"\",\n",
      "        \"additional_kwargs\": {\n",
      "          \"tool_calls\": [\n",
      "            {\n",
      "              \"id\": \"call_HAfilebE1q9E9OQHOlL3JYHP\",\n",
      "              \"type\": \"function\",\n",
      "              \"function\": \"[Object]\"\n",
      "            }\n",
      "          ]\n",
      "        },\n",
      "        \"response_metadata\": {\n",
      "          \"tokenUsage\": {\n",
      "            \"completionTokens\": 15,\n",
      "            \"promptTokens\": 59,\n",
      "            \"totalTokens\": 74\n",
      "          },\n",
      "          \"finish_reason\": \"tool_calls\",\n",
      "          \"system_fingerprint\": \"fp_157b3831f5\"\n",
      "        },\n",
      "        \"tool_calls\": [\n",
      "          {\n",
      "            \"name\": \"get_weather\",\n",
      "            \"args\": {\n",
      "              \"location\": \"San Francisco\"\n",
      "            },\n",
      "            \"type\": \"tool_call\",\n",
      "            \"id\": \"call_HAfilebE1q9E9OQHOlL3JYHP\"\n",
      "          }\n",
      "        ],\n",
      "        \"invalid_tool_calls\": [],\n",
      "        \"usage_metadata\": {\n",
      "          \"input_tokens\": 59,\n",
      "          \"output_tokens\": 15,\n",
      "          \"total_tokens\": 74\n",
      "        }\n",
      "      }\n",
      "    ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task_result',\n",
      "  timestamp: '2024-08-30T20:58:59.072Z',\n",
      "  step: 1,\n",
      "  payload: {\n",
      "    id: '768110dd-6004-59f3-8671-6ca699cccd71',\n",
      "    name: 'agent',\n",
      "    result: [ [Array] ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task',\n",
      "  timestamp: '2024-08-30T20:58:59.074Z',\n",
      "  step: 2,\n",
      "  payload: {\n",
      "    id: '76459c18-5621-5893-9b93-13bc1db3ba6d',\n",
      "    name: 'tools',\n",
      "    input: { messages: [Array] },\n",
      "    triggers: [ 'branch:agent:shouldContinue:tools' ],\n",
      "    interrupts: []\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: updates\n",
      "{\n",
      "  tools: {\n",
      "    messages: [\n",
      "      ToolMessage {\n",
      "        \"content\": \"It's 60 degrees and foggy.\",\n",
      "        \"name\": \"get_weather\",\n",
      "        \"additional_kwargs\": {},\n",
      "        \"response_metadata\": {},\n",
      "        \"tool_call_id\": \"call_HAfilebE1q9E9OQHOlL3JYHP\"\n",
      "      }\n",
      "    ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task_result',\n",
      "  timestamp: '2024-08-30T20:58:59.076Z',\n",
      "  step: 2,\n",
      "  payload: {\n",
      "    id: '76459c18-5621-5893-9b93-13bc1db3ba6d',\n",
      "    name: 'tools',\n",
      "    result: [ [Array] ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task',\n",
      "  timestamp: '2024-08-30T20:58:59.077Z',\n",
      "  step: 3,\n",
      "  payload: {\n",
      "    id: '565d8a53-1057-5d83-bda8-ba3fada24b70',\n",
      "    name: 'agent',\n",
      "    input: { messages: [Array] },\n",
      "    triggers: [ 'tools' ],\n",
      "    interrupts: []\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: updates\n",
      "{\n",
      "  agent: {\n",
      "    messages: [\n",
      "      AIMessage {\n",
      "        \"id\": \"chatcmpl-A22zrdeobsBzkiES0C6Twh3p7I344\",\n",
      "        \"content\": \"The weather in San Francisco right now is 60 degrees and foggy.\",\n",
      "        \"additional_kwargs\": {},\n",
      "        \"response_metadata\": {\n",
      "          \"tokenUsage\": {\n",
      "            \"completionTokens\": 16,\n",
      "            \"promptTokens\": 90,\n",
      "            \"totalTokens\": 106\n",
      "          },\n",
      "          \"finish_reason\": \"stop\",\n",
      "          \"system_fingerprint\": \"fp_157b3831f5\"\n",
      "        },\n",
      "        \"tool_calls\": [],\n",
      "        \"invalid_tool_calls\": [],\n",
      "        \"usage_metadata\": {\n",
      "          \"input_tokens\": 90,\n",
      "          \"output_tokens\": 16,\n",
      "          \"total_tokens\": 106\n",
      "        }\n",
      "      }\n",
      "    ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n",
      "Receiving new event of type: debug\n",
      "{\n",
      "  type: 'task_result',\n",
      "  timestamp: '2024-08-30T20:58:59.640Z',\n",
      "  step: 3,\n",
      "  payload: {\n",
      "    id: '565d8a53-1057-5d83-bda8-ba3fada24b70',\n",
      "    name: 'agent',\n",
      "    result: [ [Array] ]\n",
      "  }\n",
      "}\n",
      "\n",
      "====\n",
      "\n"
     ]
    }
   ],
   "source": [
    "let inputs = { messages: [{ role: \"user\", content: \"what's the weather in sf?\" }] };\n",
    "\n",
    "let stream = await graph.stream(inputs, {\n",
    "  streamMode: [\"updates\", \"debug\"],\n",
    "});\n",
    "\n",
    "for await (const chunk of stream) {\n",
    "  console.log(`Receiving new event of type: ${chunk[0]}`);\n",
    "  console.log(chunk[1]);\n",
    "  console.log(\"\\n====\\n\");\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "TypeScript",
   "language": "typescript",
   "name": "tslab"
  },
  "language_info": {
   "codemirror_mode": {
    "mode": "typescript",
    "name": "javascript",
    "typescript": true
   },
   "file_extension": ".ts",
   "mimetype": "text/typescript",
   "name": "typescript",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
